package com.alingrad.android.froyoengine.util;

import java.io.IOException;
import java.io.InputStream;

import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.opengl.GLUtils;

import com.alingrad.android.froyoengine.collisions.CollisionMaskData;
import com.alingrad.android.froyoengine.graphics.Texture;

public abstract class TextureLoader {

	private static Context sContext;
	private static boolean sReady = false;

	public static void prepare(Context context) {
		sContext = context;
		sReady = true;
	}

	private static int createID(GL10 gl) {
		int[] ids = new int[1];
		gl.glGenTextures(1, ids, 0);
		return ids[0];
	}

	private static CollisionMaskData createCollisionMaskData(Bitmap bitmap) {
		int xmin = bitmap.getWidth();
		int xmax = 0;
		int ymin = bitmap.getHeight();
		int ymax = 0;
		for (int y = 0; y < bitmap.getHeight(); y++) {
			for (int x = 0; x < bitmap.getWidth(); x++) {
				if (Color.alpha(bitmap.getPixel(x, y)) > 0) {
					if (x < xmin)
						xmin = x;
					if (x > xmax)
						xmax = x;
					if (y < ymin)
						ymin = y;
					if (y > ymax)
						ymax = y;
				}
			}
		}
		int width = xmax - xmin + 1;
		int height = ymax - ymin + 1;
		if (width < 0)
			width = 0;
		if (height < 0)
			height = 0;
		final int xCenter = bitmap.getWidth() / 2;
		final int yCenter = bitmap.getHeight() / 2;
		return new CollisionMaskData(xmin - xCenter, (bitmap.getHeight() - ymax) - yCenter, width, height);
	}

	public static Texture loadTexture(GL10 gl, final int ref, final boolean collidable) {
		if (!sReady) {
			throw new RuntimeException("Texture Loader not prepared");
		}
		InputStream is = sContext.getResources().openRawResource(ref);
		Bitmap bitmap = null;
		try {
			bitmap = BitmapFactory.decodeStream(is);
		} finally {
			try {
				is.close();
				is = null;
			} catch (IOException e) {
			}
		}

		int id = createID(gl);
		int target = GL10.GL_TEXTURE_2D;

		Texture texture;

		CollisionMaskData data = createCollisionMaskData(bitmap);
		
		if (!collidable)
			texture = new Texture(target, id, bitmap.getWidth(), bitmap.getHeight(), null);
		else
			texture = new Texture(target, id, bitmap.getWidth(), bitmap.getHeight(), data);

		gl.glBindTexture(target, id);

		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);

		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

		bitmap.recycle();

		return texture;
	}
}
